package linter.linterjava.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import linter.linterjava.POJO.DO.ModelResult;
import linter.linterjava.POJO.DO.ModelUserData;
import linter.linterjava.POJO.UtilDTO.ModelUploadUtilDTO;
import linter.linterjava.POJO.UtilDTO.TypeDTO;
import linter.linterjava.mapper.ModelResultMapper;
import linter.linterjava.service.ModelUserDataService;
import linter.linterjava.mapper.ModelUserDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.annotation.Resource;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static linter.linterjava.custom.ConstantPublicWay.*;
import static linter.linterjava.custom.CustomResultType.PREPROCESS_ERROR;
import static linter.linterjava.custom.CustomResultType.PREPROCESS_SUCCESS;


/**
* @author 北煜
* @description 针对表【model_user_data(用户数据上传记录表)】的数据库操作Service实现
* @createDate 2024-07-15 18:04:29
*/
@Service
@Slf4j
public class ModelUserDataServiceImpl extends ServiceImpl<ModelUserDataMapper, ModelUserData>
    implements ModelUserDataService{

    @Resource
    ModelResultMapper modelResultMapper;
    @Resource
    ModelUserDataMapper modelUserDataMapper;

    /**
     *  需要传递 1.特征目标 2.模型参数 3.modelUserData的id 4.uuid
     */
    @Override
    public String linearRegression(ModelUploadUtilDTO modelUploadUtilDTO, Long uuid) {
        log.info("开始进行线性回归");

        // 查询特征列、训练数据和测试数据
        List<ModelUserData> modelUserDataList = getList(new QueryWrapper<ModelUserData>()
                .eq("id", modelUploadUtilDTO.getId())
                .eq("user_id", uuid)
                .eq("is_delete", 0), modelUserDataMapper);

        // 检查特征列、训练数据和测试数据是否为空
        List<String> featureColumns = modelUserDataList.stream()
                .map(ModelUserData::getTrainSelecetField)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<String> trainDataUrls = modelUserDataList.stream()
                .map(ModelUserData::getTrainDataUrl)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<String> testDataUrls = modelUserDataList.stream()
                .map(ModelUserData::getTestDataUrl)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (featureColumns.isEmpty()) {
            return "特征列不能为空";
        }
        if (trainDataUrls.isEmpty()) {
            return "训练数据不能为空";
        }
        if (testDataUrls.isEmpty()) {
            return "测试数据不能为空";
        }

        // 构建请求参数
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("featureColumn", modelUploadUtilDTO.getFeatureColumn());
        params.add("modelColumn", modelUploadUtilDTO.getModelTypeColum());
        params.add("featureColumns", featureColumns);
        params.add("trainDataUrl", trainDataUrls);
        params.add("testDataUrl", testDataUrls);

        // 发送请求并处理响应
        try {
            ResponseEntity<String> response = sendPostRequest("http://127.0.0.1:5000/Linear", params);
            if (response.getStatusCode().is2xxSuccessful()) {
                String main = processResponse("http://127.0.0.1:5000/LinearMain");
                if (response.getStatusCode().is2xxSuccessful()) {
                    Date date = new Date();
                    ModelResult modelResult = new ModelResult();
                    modelResult.setModelId(modelUploadUtilDTO.getModelId());
                    modelResult.setUserId(uuid);
                    modelResult.setModelEvaluate(main);
                    modelResult.setResult(main);
                    modelResult.setCreateTime(date);
                    modelResult.setUpdataTime(date);
                    int flag = modelResultMapper.insert(modelResult);
                    return flag > 0 ? PREPROCESS_SUCCESS : PREPROCESS_ERROR;
                }
            }
        } catch (Exception e) {
            log.error("线性回归接口调用失败", e);
        }

        return PREPROCESS_ERROR;
    }
}




